<?php

namespace Modules\Idoc\Providers;

use Closure;
use Duxravel\Core\UI\Widget;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider as BaseServiceProvider;
use Modules\Idoc\Repository\ConfigRepository;
use Modules\Idoc\UI\Component\TreeView;
use Modules\Idoc\Util\FileWriter;
use Modules\Idoc\Util\Rewrite;

class ConfigServiceProvider extends BaseServiceProvider
{
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        // Bind it only once so we can reuse in IoC
        $this->app->singleton($this->repository(), function($app, $items) {
            $writer = new FileWriter($this->getFiles(), $this->getConfigPath());
            return new ConfigRepository($writer, $items);
        });

        $this->app->extend('config', function($config, $app) {
            $config_items = $config->all();
            return $app->make($this->repository(), $config_items);
        });

        /**
         * php artisan idoc:generate
         * 例子:
         * Config::write('app.url', 'http://domain.com');
         * app('config')->write('app.url', 'http://domain.com');
         * $writeConfig = new Modules\Idoc\Util\Rewrite;
         * $writeConfig->toFile('path/to/config.php', [
            'item' => 'new value',
            'nested.config.item' => 'value',
            'arrayItem' => ['Single', 'Level', 'Array', 'Values'],
            'numberItem' => 3,
            'booleanItem' => true
            ]);
         */
    }

    public function repository(): string
    {
        return ConfigRepository::class;
    }

    protected function getFiles(): Filesystem
    {
        return $this->app['files'];
    }

    protected function getConfigPath(): string
    {
        return $this->app['path.config'];
    }

    public function setTextSvg($text,$bg,$size = 24, $x = 0,$y = 0): string
    {
        return '<svg xmlns="http://www.w3.org/2000/svg" class="inline-block" version="1.1" height="'.$size.'" width="'.($size+12).'"><rect fill="' . $bg . '" x="'.$x.'" y="'.$y.'" width="'.($size+12).'" rx="8" ry="8" height="'.$size.'"></rect><text x="'.(($size+12)/2).'" y="'.($size/2).'" font-size="'.($size/2).'" text-copy="fast" fill="#FFFFFF" text-anchor="middle" text-rights="admin" dominant-baseline="central">' . $text . '</text></svg>';
    }

    public function boot()
    {
        $routes = Route::getRoutes()->getRoutes();
        $appGroups = [];
        foreach ($routes as $route){
            if(in_array('api',$route->action['middleware'])&&isset($route->action['app'])&&$route->action['app']){
                $appGroups[$route->action['app']][$route->action['group']][] = $route;
            }
        }
        $tag_groups = [];
        $api_routes = [];
        foreach ($appGroups as $name=>$value){
            $id = md5($name.uniqid());
            $keys = array_keys($value);
            $twoRoutes = [];
            foreach ($keys as $key){
                $twoId = md5($key.uniqid());
                $threeRoutes = [];
                foreach ($value[$key] as $route){
                    $threeId = md5($route->uri);
                    $icon = '';
                    if (in_array('GET',$route->methods)){
                        $icon = $this->setTextSvg("GET","#00B42A");
                    }elseif (in_array('POST',$route->methods)){
                        $icon = $this->setTextSvg("POST","#8D4EDA");
                    }elseif (in_array('PUT',$route->methods)){
                        $icon = $this->setTextSvg("PUT","#FFCF8B");
                    }elseif (in_array('DELETE',$route->methods)){
                        $icon = $this->setTextSvg("DELETE","#FFECE8");
                    }
                    $threeRoutes[] = ['id'=>$threeId, 'pid'=>$twoId, 'name'=>$route->action['desc'], 'type'=>2, 'icon'=>$icon,'children'=>[],'route'=>$route];
                }
                $twoRoutes[] = ['id'=>$twoId, 'pid'=>$id, 'name'=>$key, 'type'=>1, 'icon'=>'icon-common','children'=>$threeRoutes];
            }
            $tag_groups[] = ['name'=>$name,'tags'=>$keys];
            $api_routes[] = ['id'=>$id, 'pid'=>0, 'name'=>$name, 'type'=>0, 'icon'=>'icon-apps' ,'children'=>$twoRoutes];
        }
        Cache::put('api_routes',json_encode($api_routes,JSON_UNESCAPED_UNICODE));
        $writeConfig = new Rewrite;
        $writeConfig->toFile(module_path('idoc/config/idoc.php'),[
            'tag_groups'=>$tag_groups
        ]);
        Blade::component('tree-view', TreeView::class);
    }
}
